<!DOCTYPE html>
<html>
<head>
    <!--Import Google Icon Font-->
    <link type="text/css" rel="stylesheet" href="css/material-icons.css"/>
    <!--Import materialize.css-->
    <link type="text/css" rel="stylesheet" href="css/materialize.min.css" media="screen,projection"/>
    <title>Instance List</title>

    <!--Let browser know website is optimized for mobile-->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <style>
        nav.clean {
            background: none;
            box-shadow: none;
        }

        .breadcrumb:before {
            color: rgba(0, 0, 0, 0.7);
        }

        .breadcrumb, .breadcrumb:last-child {
            color: rgba(0, 0, 0, 1);
        }
    </style>
</head>
<body>

<div class="container">
    <div class="section">
        <nav class="clean">
            <div class="nav-wrapper">
                <div class="col s12" id="breadcrumb-path">
                    <a href="/compute_pools.html" class="breadcrumb" id="pool-caption"></a>
                </div>
            </div>
        </nav>
    </div>
    <div class="divider"></div>
    <div class="section">
        <div class="row">
            <div class="col m9 s8" id="button_panel">
                <a class="waves-effect waves-light blue-grey lighten-2 btn" id="create_button"><i class="material-icons left">add</i></a>
                <a class="waves-effect waves-light blue-grey lighten-2 btn" id="batch_create_button"><i class="material-icons left">playlist_add</i></a>
            </div>
            <div class="col m3 s4" id="autofresh">
            </div>
        </div>
    </div>
    <div class="section" id="instance_list">
    </div>
    <div class="modal" id="delete_modal">
        <div class="modal-content">
            <h4>Delete Confirm</h4>
            <p id="delete_confirm_content"></p>
        </div>
        <div class="modal-footer">
            <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
            <a href="#" class="modal-close waves-effect waves-green btn-flat" id="delete_confirm_link">Yes</a>
        </div>
    </div>
    <div class="modal" id="media_modal">
        <!--hide model -->
        <div class="modal-content">
            <h4>Start guest with media</h4>
            <div class="row">
              <div class="input-field col m4">
                  <select name="media" id="media_options">
                  </select>
                  <label>Choose Media</label>
              </div>
            </div>
        </div>
        <div class="modal-footer">
            <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
            <a href="#" class="modal-close waves-effect waves-green btn-flat" id="media_confirm_link">Yes</a>
        </div>
    </div>
    <div class="modal" id="insert_modal">
        <!--hide model -->
        <div class="modal-content">
            <h4>Insert media into instance</h4>
            <div class="row">
              <div class="input-field col m4">
                  <select name="media" id="insert_options">
                  </select>
                  <label>Choose Media</label>
              </div>
            </div>
        </div>
        <div class="modal-footer">
            <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
            <a href="#" class="modal-close waves-effect waves-green btn-flat" id="insert_confirm_link">Yes</a>
        </div>
    </div>
    <div class="modal" id="eject_modal">
        <!--hide model -->
        <div class="modal-content">
            <h4>Eject media from instance</h4>
            <p id="eject_confirm_content"></p>
        </div>
        <div class="modal-footer">
            <a href="#" class="modal-close waves-effect waves-green btn-flat">No</a>
            <a href="#" class="modal-close waves-effect waves-green btn-flat" id="eject_confirm_link">Yes</a>
        </div>
    </div>
    <div class="modal" id="migrate-modal">
        <!--hide model -->
        <div class="modal-content">
            <h4>Migrate Instance</h4>
            <div class="row">
              <p id="migrate-content">
              </p>
              <input type="hidden" id="migrate-pool">
              <input type="hidden" id="migrate-source">
            </div>
            <div class="row">
              <div class="input-field col m4">
                  <select name="migrate-target" id="migrate-target-options">
                  </select>
                  <label>Target Cell</label>
              </div>
            </div>
        </div>
        <div class="modal-footer">
            <a href="#" class="modal-close waves-effect waves-green btn-flat"></a>
            <a href="#" class="modal-close waves-effect waves-green btn-flat" id="migrate-confirm-link"></a>
        </div>
    </div>
    <div class="modal" id="batch-modal">
        <!--hide model -->
        <div class="modal-content" id="batch-modal-content">
        </div>
        <div class="modal-footer">
            <a href="#" class="modal-close waves-effect waves-green btn-flat"></a>
            <a href="#" class="modal-close waves-effect waves-green btn-flat" id="batch-button-confirm"></a>
        </div>
    </div>
</div>

<!--JavaScript at end of body for optimized loading-->
<script type="text/javascript" src="/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/js/materialize.min.js"></script>
<script type="text/javascript" src="js/nano.js"></script>
<script>
    N.ValidateSession();
    var texts = N.GetTexts();
    $('#create_button').append(texts.get(N.TagCreate));
    $('#pool-caption').text(texts.get(N.TagComputePool));
    $('.modal-footer > a:first-child').text(texts.get(N.TagCancel));
    $('.modal-footer > a:last-child').text(texts.get(N.TagConfirm));
    if (N.IsChinese()){
      $('#batch_create_button').append('批量创建');
    }else{
      $('#batch_create_button').append('Batch Create');
    }

    var poolName;
    var cellName;
    var batchModeEnabled = false;

    M.AutoInit();

    function enableAutoFreshSwitch(){
      //auto fresh switch
      $('#autofresh').append(
        $('<span>').text(texts.get(N.TagAutoFresh))
      ).append(
        $('<div>').addClass('switch').append(
          $('<label>').append(texts.get(N.TagOff)).append(
            $('<input>').attr('type', 'checkbox').attr('onclick', 'onAutoFreshSwitched()').attr('id', 'switch-autofresh').prop('checked', true)
          ).append(
            $('<span>').addClass('lever')
          ).append(texts.get(N.TagOn))
        )
      );
      //enable auto fresh in default
      intervalID = setInterval(refresh, refreshInterval);
    }

    function disableAutoFreshSwitch(){
      if(intervalID){
        clearInterval(intervalID);
        intervalID = undefined;
      }
      $('#autofresh').empty();
    }

    function disableBatchMode(){
      //load button
      var panel = $('#button_panel');
      var enableButton = $('<a>').addClass('waves-effect waves-light blue-grey lighten-2 btn').attr('id', 'enable_batch_button')
        .attr('onclick', 'enableBatchMode()').append(
          $('<i>').addClass('material-icons left').text('list')
      );
      if (N.IsChinese()){
        enableButton.append('批量处理');
      }else{
        enableButton.append('Batch Mode');
      }
      $('#batch_delete_button').remove();
      $('#batch_stop_button').remove();
      $('#disable_batch_button').remove();
      panel.append(enableButton);
      batchModeEnabled = false;
      enableAutoFreshSwitch();
      loadInstances();
    }

    function enableBatchMode(){
      disableAutoFreshSwitch();
      //load button
      var panel = $('#button_panel');
      var deleteButton = $('<a>').addClass('waves-effect waves-light blue-grey lighten-2 btn').attr('id', 'batch_delete_button').attr('onclick', 'confirmBatchDelete()').append(
        $('<i>').addClass('material-icons left').text('delete')
      );
      var stopButton = $('<a>').addClass('waves-effect waves-light blue-grey lighten-2 btn').attr('id', 'batch_stop_button').attr('onclick', 'confirmBatchStop()').append(
        $('<i>').addClass('material-icons left').text('power_settings_new')
      );
      var disableButton = $('<a>').addClass('waves-effect waves-light red lighten-2 btn').attr('id', 'disable_batch_button')
        .attr('onclick', 'disableBatchMode()').append(
          $('<i>').addClass('material-icons left').text('done')
      );
      if (N.IsChinese()){
        deleteButton.append('批量删除');
        stopButton.append('批量停止');
        disableButton.append('完成批量处理');
      }else{
        deleteButton.append('Batch Delete');
        stopButton.append('Batch Stop');
        disableButton.append('Exit Batch Mode');
      }
      $('#enable_batch_button').remove();
      panel.append(deleteButton);
      panel.append(stopButton);
      panel.append(disableButton);
      batchModeEnabled = true;
      loadInstances();
    }

    function switchAllInstances(){
      if ($("input[name='all-checkbox']:checkbox").prop('checked')) {
        $("input[name='batch-target']").prop('checked', true);
      }else{
        $("input[name='batch-target']").prop('checked', false);
      }
    }

    function parseQueryString(){
      var url = window.location.search;
      var queryParams = new Map();
      var queryString = url.substring( url.indexOf('?') + 1 );
      if (0 === queryString.length){
        return queryParams;
      }
      var values = queryString.split("&");
      values.forEach((value) => {
        var p = value.split('=');
        queryParams.set(p[0], p[1]);
      });
      return queryParams;
    }

    function refresh(){
      loadInstances();
    }

    function outputMessage(message){
      $('#instance_list').empty().append(
        $('<div>').addClass('center').append(
          $('<span>').text(message)
        )
      );
    }

    function loadInstances(){
      if (!poolName){
        return;
      }
      var url = "/guest_search/?pool=" + poolName + '&session=' + N.GetSessionID();
      if (cellName){
        url += "&cell=" + cellName;
      }
      $.getJSON(
        url,
        function(result){
          if (0 != result['error_code']) {
            outputMessage(result['message']);
            return;
          }
          if (!result['data']){
            outputMessage('no instance available');
            $('#instance_list').empty();
            return
          }
          if (0 == result['data'].length){
            outputMessage('no instance available');
            return;
          }
          var parent = $('#instance_list').empty();
          var container = $('<div>').addClass('row');
          var instanceTitle = $('<td>');
          if (batchModeEnabled){
            var textSpan = $('<span>');
            if (N.IsChinese()){
              textSpan.text('全选');
            }else{
              textSpan.text('All Instances');
            }
            instanceTitle.append(
              $('<label>').append(
                $('<input>').attr('type', 'checkbox').addClass('filled-in')
                  .attr('name', 'all-checkbox').attr('onclick', 'switchAllInstances()')
              ).append(textSpan)
            )
          }else{
            instanceTitle.text(texts.get(N.TagName));
          }

          var table = $('<table>').append(
            $('<thead>').append(
              $('<tr>').append(
                instanceTitle
              ).append(
                $('<td>').text(texts.get(N.TagCell))
              ).append(
                $('<td>').text(texts.get(N.TagAddress))
              ).append(
                $('<td>').text(texts.get(N.TagCore))
              ).append(
                $('<td>').text(texts.get(N.TagMemory))
              ).append(
                $('<td>').text(texts.get(N.TagDisk))
              ).append(
                $('<td>').text(texts.get(N.TagStatus))
              ).append($('<td>'))
            )
          );
          var MiB = 1 << 20;
          var GiB = 1 << 30;
          result['data'].forEach((instance) => {
            var instanceID = instance['id'];
            var instanceName = instance['name'];
            var mediaAttached = instance['media_attached'];
            var titleContent = $('<td>');
            if (batchModeEnabled){
              titleContent.append(
                $('<label>').append(
                  $('<input>').attr('type', 'checkbox').addClass('filled-in')
                    .attr('name', 'batch-target').val(instanceID)
                ).append($('<span>').text(instanceName))
              )
            }else{
              titleContent.text(instanceName);
            }

            var content = $('<tr>');
            content.append(
              titleContent
            ).append(
              $('<td>').text(instance['cell'])
            );
            if (instance['internal'] && instance['internal']['network_address']){
              content.append(
                $('<td>').text(instance['internal']['network_address'])
              );
            }else{
              content.append($('<td>'));
            }

            content.append(
              $('<td>').text(instance['cores'])
            );
            if (instance['memory'] > GiB){
              //gb
              content.append(
                $('<td>').text(Math.floor(instance['memory'] * 100 / GiB) / 100 + ' GiB')
              );
            }else{
              content.append(
                $('<td>').text(Math.floor(instance['memory'] * 100 / MiB) / 100 + ' MiB')
              )
            }
            //disk
            var disks = new Array();
            instance['disks'].forEach((size) => {
              disks.push(Math.floor(size * 100 / GiB) / 100);
            });
            content.append(
              $('<td>').text(disks.join(' / ') + ' GiB')
            )

            var operators = $('<td>');
            var status = $('<td>');
            //Status
            if (instance['lost']){
              status.append(
                $('<i>').addClass('material-icons orange-text darken-2 tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagLost)).text('cloud_off')
              );
            }
            else if (instance['running']){
              //running
              status.append(
                $('<i>').addClass('material-icons green-text darken-2 tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagRunning)).text('play_arrow')
              );
              operators.append(
                $('<a>').attr('href', 'instance_control.html?instance=' + instanceID).addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagRemoteControl)).attr('target', '_blank').append(
                    $('<i>').addClass('material-icons').text('desktop_windows')
                  )
              );
              operators.append(
                $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagStop)).append(
                    $('<i>').addClass('material-icons').text('power_settings_new')
                  ).click(function(){
                    N.StopInstance(instanceName, instanceID, refresh);
                  })
              );
              operators.append(
                $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagForceStop)).append(
                    $('<i>').addClass('material-icons').text('power')
                  ).click(function(){
                    N.ForceStopInstance(instanceName, instanceID, refresh);
                  })
              );
              operators.append(
                $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagReboot)).append(
                    $('<i>').addClass('material-icons').text('rotate_right')
                  ).click(function(){
                    N.RestartInstance(instanceName, instanceID, refresh);
                  })
              );
              operators.append(
                $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagForceReboot)).append(
                    $('<i>').addClass('material-icons').text('refresh')
                  ).click(function(){
                    N.ResetInstance(instanceName, instanceID, refresh);
                  })
              );
              if (mediaAttached){
                status.append(
                    $('<i>').addClass('material-icons green-text darken-2 tooltipped').attr('data-position', 'top').
                      attr('data-tooltip', texts.get(N.TagMediaAttached)).text('album')
                );
                operators.append(
                  $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                    attr('data-tooltip', texts.get(N.TagEjectMedia)).attr('onclick', 'confirmEject("' + instanceName + '","' + instanceID + '")').append(
                      $('<i>').addClass('material-icons').text('eject')
                    )
                );
              }else{
                operators.append(
                  $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                    attr('data-tooltip', texts.get(N.TagInsertMedia)).attr('onclick', 'selectInsertMedia("' + instanceName + '","' + instanceID + '")').append(
                      $('<i>').addClass('material-icons').text('arrow_drop_down')
                    )
                );
              }
            }else{
              //stopped
              status.append(
                  $('<i>').addClass('material-icons red-text darken-4 tooltipped').attr('data-position', 'top').
                    attr('data-tooltip', texts.get(N.TagStopped)).text('stop')
              );
              operators.append(
                $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagStart)).append(
                    $('<i>').addClass('material-icons').text('play_arrow')
                  ).click(function(){
                    N.StartInstance(instanceName, instanceID, refresh);
                  })
              );
              operators.append(
                $('<a>').attr('href', '#').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagStartWithMedia)).attr('onclick', 'selectMedia("' + instanceName + '","' + instanceID + '")').append(
                    $('<i>').addClass('material-icons').text('play_circle_outline')
                  )
              );
              operators.append(
                $('<a>').attr('href', 'snapshots.html?pool=' + poolName + '&instance=' + instanceID).addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagSnapshot)).attr('target', '_blank').append(
                    $('<i>').addClass('material-icons').text('photo_camera')
                  )
              );
              operators.append(
                $('<a>').attr('href', 'build_image.html?instance=' + instanceID).addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagBuildDiskImage)).attr('target', '_blank').append(
                    $('<i>').addClass('material-icons').text('cloud_upload')
                  )
              );
              var resetURL = 'reset_system.html?origin=list&instance=' + instanceID + '&name=' + instanceName + '&pool=' + poolName;
              if(cellName){
                resetURL += cellName;
              }
              operators.append(
                $('<a>').attr('href', resetURL).addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagResetSystem)).attr('target', '_self').append(
                    $('<i>').addClass('material-icons').text('replay')
                  )
              );
              operators.append(
                $('<a>').attr('href', '#').attr('onclick', 'confirmDelete("' + instanceName + '","' + instanceID + '")').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagDelete)).append(
                    $('<i>').addClass('material-icons').text('delete')
                  )
              );
              operators.append(
                $('<a>').attr('href', '#').attr('onclick', 'confirmMigrate("' + instanceName + '","' + instanceID + '")').addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                  attr('data-tooltip', texts.get(N.TagMigrate)).append(
                    $('<i>').addClass('material-icons').text('local_shipping')
                  )
              );
            }

            //auto_start
            if (instance['auto_start']){
              status.append(
                  $('<i>').addClass('material-icons green-text darken-2 tooltipped').attr('data-position', 'top').
                    attr('data-tooltip', texts.get(N.TagAutoStart) + ' ' + texts.get(N.TagEnable)).text('all_inclusive')
                );
            }

            content.append(status);
            var monitorUrl = "monitor_instance_status.html?pool=" + poolName + '&instance=' + instanceID;
            var detailURL = "instance_detail.html?pool=" + poolName + '&instance=' + instanceID;
            if (cellName){
              monitorUrl += "&cell=" + cellName;
              detailURL += "&cell=" + cellName;
            }
            operators.append(
              $('<a>').attr('href', monitorUrl).addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                attr('data-tooltip', texts.get(N.TagMonitor)).attr('target', '_blank').append(
                  $('<i>').addClass('material-icons').text('show_chart')
                )
            );
            operators.append(
              $('<a>').attr('href', detailURL).addClass('blue-grey-text tooltipped').attr('data-position', 'top').
                attr('data-tooltip', texts.get(N.TagDetail)).attr('target', '_blank').append(
                  $('<i>').addClass('material-icons').text('settings')
                )
            );
            content.append(operators);
            container.append(
              table.append(content)
            );
          });
          parent.append(container);
          $('.material-tooltip').remove();
          M.Tooltip.init($('.tooltipped'));
        }
      );
    }

    function selectMedia(name, id){
      $('#media_confirm_link').attr('onclick', 'startWithMedia("' + name + '", "' + id +'")');
      var queryURL = '/media_image_search/?session=' + N.GetSessionID();
      $.getJSON(
        queryURL,
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'fetch media fail: ' + result['message'], outDuration: 600});
              return;
          }
          if (!result['data']){
            M.toast({html: 'no media image available', outDuration: 600});
            return;
          }
          $('#media_options').empty();
          result['data'].forEach((media)=>{
            $('#media_options').append(
              $('<option>').attr('value', media['id']).text(media['name'])
            );
          });
          M.FormSelect.init($('#media_options'));
          var instance = M.Modal.getInstance($('#media_modal'));
          instance.open();
        }
      )
    }

    function startWithMedia(name, id){
      var media = $('#media_options').val();
      var mediaName = $('#media_options :selected').text();
      $.post(
        '/instances/' + id,
        JSON.stringify({
          "from_media": true,
          "source": media
        }),
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'start instance fail: ' + result['message'], outDuration: 1000});
              return;
          }
          M.toast({html: 'instance "' + name + '" started with media ' + mediaName});
          setTimeout(refresh, 3000);
          N.WriteOperateLog('start instance ' + name + ' / ' + id + ' with media ' + mediaName);
        },
        "json"
      );
    }

    function confirmDelete(name, id){
      $('#delete_confirm_content').text('Are you sure to delete guest ' + name);
      $('#delete_confirm_link').attr('onclick', 'deleteGuest("' + name + '", "' + id +'")');
      var instance = M.Modal.getInstance($('#delete_modal'));
      instance.open();
    }

    function deleteGuest(name, id) {
      $.ajax({
       url:'/guests/' + id,
       type: "DELETE",
       dataType: "json",
       data:JSON.stringify({
           "force": false
       }),
       success: function (result) {
           if (0 != result['error_code']) {
               M.toast({html: 'delete guest fail: ' + result['message'], outDuration: 1000});
               return;
           }
           M.toast({html: 'guest "' + name + '" deleted'})
           setTimeout(refresh, 500);
           N.WriteOperateLog('delete guest ' + name + ' / ' + id);
       }
      });
    }

    //insert media
    function selectInsertMedia(name, id){
      $('#insert_confirm_link').attr('onclick', 'insertMedia("' + name + '", "' + id +'")');
      var queryURL = '/media_image_search/?session=' + N.GetSessionID();
      $.getJSON(
        queryURL,
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'fetch media fail: ' + result['message'], outDuration: 600});
              return;
          }
          $('#insert_options').empty();
          result['data'].forEach((media)=>{
            $('#insert_options').append(
              $('<option>').attr('value', media['id']).text(media['name'])
            );
          });
          M.FormSelect.init($('#insert_options'));
          var instance = M.Modal.getInstance($('#insert_modal'));
          instance.open();
        }
      )
    }

    function insertMedia(name, id){
      var media = $('#insert_options').val();
      var mediaName = $('#insert_options :selected').text();
      $.post(
        '/instances/' + id + '/media',
        JSON.stringify({
          "source": media
        }),
        function(result){
          if (0 != result['error_code']) {
              M.toast({html: 'insert media fail: ' + result['message'], outDuration: 1000});
              return;
          }
          M.toast({html: 'media "' + mediaName + '" insert into ' + name });
          setTimeout(refresh, 3000);
        },
        "json"
      );
    }

    //eject media
    function confirmEject(name, id){
      $('#eject_confirm_content').text('Are you sure to eject media of guest ' + name);
      $('#eject_confirm_link').attr('onclick', 'ejectMedia("' + name + '", "' + id +'")');
      var instance = M.Modal.getInstance($('#eject_modal'));
      instance.open();
    }

    function ejectMedia(name, id) {
      $.ajax({
       url:'/instances/' + id + '/media',
       type: "DELETE",
       dataType: "json",
       data:JSON.stringify({
       }),
       success: function (result) {
           if (0 != result['error_code']) {
               M.toast({html: 'eject media fail: ' + result['message'], outDuration: 1000});
               return;
           }
           M.toast({html: 'media of guest "' + name + '" ejected'})
           setTimeout(refresh, 500);
       }
      });
    }

    //migrate instance
    function confirmMigrate(name, id){
      $('#migrate-confirm-link').attr('onclick', 'migrateInstance("' + name + '", "' + id +'")');
      $.getJSON(
        '/guests/' + id,
        function(result){
          if (0 != result['error_code']) {
            M.toast({html: 'get instance config fail: ' + result['message']});
            return;
          }
          if (!result['data']){
            M.toast({html: 'no config available for instance "' + name + '"'});
            return;
          }
          var config = result['data'];
          var poolName = config['pool'];
          var currentCell = config['cell'];
          $.getJSON(
            '/compute_pool_cells/' + poolName,
            function(result){
              if (0 != result['error_code']) {
                M.toast({html: 'query cells fail: ' + result['message']});
                return;
              }
              if (!result['data']){
                M.toast({html: 'no cell available in pool "' + poolName + '"'});
                return;
              }
              if (0 == result['data'].length){
                M.toast({html: 'no cell available in pool "' + poolName + '"'});
                return;
              }
              var options = $('#migrate-target-options').empty();
              var currentAddress = "";
              result['data'].forEach((cell)=>{
                var cellName = cell['name'];
                var displayText = cellName + '('+ cell['address']+')';
                if (cellName == currentCell){
                  currentAddress = displayText;
                  return;
                }
                if (!cell['enabled']){
                  options.append(
                    $('<option>').attr('value', cellName).text(displayText + ' - Disabled').prop('disabled', true)
                  );
                }else if(!cell['alive']){
                  options.append(
                    $('<option>').attr('value', cellName).text(displayText + ' - Lost').prop('disabled', true)
                  );
                }else{
                  options.append(
                    $('<option>').attr('value', cellName).text(displayText)
                  );
                }
              });
              M.FormSelect.init($('#migrate-target-options'));
              if (currentAddress){
                $('#migrate-content').text('Migrate instance "' + name + '" from "' + currentAddress + '" to');
              }else{
                $('#migrate-content').text('Migrate instance "' + name + '" from "' + currentCell + '" to');
              }
              $('#migrate-pool').val(poolName);
              $('#migrate-source').val(currentCell);
              var instance = M.Modal.getInstance($('#migrate-modal'));
              instance.open();
            }
          );
        }
      );

    }

    function migrateInstance(name, id){
      var poolName = $('#migrate-pool').val();
      var sourceCell = $('#migrate-source').val();
      var targetCell = $('#migrate-target-options').val();
      if (!targetCell){
        M.toast({html: "invalid target cell"});
        return;
      }
      var request = new Object();
      request.source_pool = poolName;
      request.source_cell = sourceCell;
      request.target_cell = targetCell;
      request.instances = [id];
      $.post(
        '/migrations/',
        JSON.stringify(request),
        function(result){
          if (0 != result['error_code']) {
            M.toast({html: 'migrate instance fail: ' + result['message']});
            return;
          }
          if (!result['data']){
            M.toast({html: 'migrate summited, but no data available'});
            return;
          }
          var migration = result['data'];
          M.toast({html: 'try migrate "'+ name +'" to "'+targetCell+'"'});
        },
        "json"
      );
    }


    function confirmBatchDelete(){
      var targets = new Array();
      $("input[name='batch-target']:checkbox:checked").each(function(){
        targets.push($(this).val());
      });
      if (0 === targets.length){
        M.toast({html: 'Must select an instance'});
        return;
      }
      var targetCount = targets.length;
      var modal = M.Modal.getInstance($('#batch-modal'));
      var content = $('#batch-modal-content').empty().append($('<h4>').text('Batch Delete Guest'));
      if(N.IsChinese()){
        content.append(
          $('<div>').text('确认删除这' + targetCount + '个实例吗？')
        );
      }else{
        content.append(
          $('<div>').text('Are you sure to delete ' + targetCount + ' instance(s)?')
        );
      }
      $('#batch-button-confirm').attr('onclick', 'batchDeleteGuest()');
      modal.open();
    }

    function batchDeleteGuest(){
      var baseBatchDeleteURL = "batch_delete_instance.html";
      var targets = new Array();
      $("input[name='batch-target']:checkbox:checked").each(function(){
        targets.push($(this).val());
      });
      if (0 === targets.length){
        M.toast({html: 'Must select an instance'});
        return;
      }
      var redirectURL = baseBatchDeleteURL + "?targets=" + encodeURIComponent(JSON.stringify(targets));
      var cellName = $('#cell-options').val();
      if (cellName){
        redirectURL += '&cell=' + cellName;
      }
      var poolName = $('#pool-options').val();
      if (poolName){
        redirectURL += '&pool=' + poolName;
      }
      window.location.href = redirectURL;
    }

    function confirmBatchStop(){
      var targets = new Array();
      $("input[name='batch-target']:checkbox:checked").each(function(){
        targets.push($(this).val());
      });
      if (0 === targets.length){
        M.toast({html: 'Must select an instance'});
        return;
      }
      var targetCount = targets.length;
      var modal = M.Modal.getInstance($('#batch-modal'));
      var content = $('#batch-modal-content').empty().append($('<h4>').text('Batch Stop Guest'));
      if(N.IsChinese()){
        content.append(
          $('<div>').text('确认停止这' + targetCount + '个实例吗？')
        );
      }else{
        content.append(
          $('<div>').text('Are you sure to stop ' + targetCount + ' instance(s)?')
        );
      }
      $('#batch-button-confirm').attr('onclick', 'batchStopGuest()');
      modal.open();
    }

    function batchStopGuest(){
      var baseBatchDeleteURL = "batch_stop_instance.html";
      var targets = new Array();
      $("input[name='batch-target']:checkbox:checked").each(function(){
        targets.push($(this).val());
      });
      if (0 === targets.length){
        M.toast({html: 'Must select an instance'});
        return;
      }
      var redirectURL = baseBatchDeleteURL + "?targets=" + encodeURIComponent(JSON.stringify(targets));
      var cellName = $('#cell-options').val();
      if (cellName){
        redirectURL += '&cell=' + cellName;
      }
      var poolName = $('#pool-options').val();
      if (poolName){
        redirectURL += '&pool=' + poolName;
      }
      window.location.href = redirectURL;
    }


    var intervalID;
    var refreshInterval = 5*1000;
    function onAutoFreshSwitched(){
      var autoFresh = $('#switch-autofresh').prop( "checked");
      if (autoFresh){
        intervalID = setInterval(refresh, refreshInterval);
        M.toast({html: "Auto Fresh Enabled"});
      }else{
        clearInterval(intervalID);
        intervalID = undefined;
        M.toast({html: "Auto Fresh Disabled"});
      }
    }

    $(function(){
      M.Modal.init($('.modal'));
      var params = parseQueryString();
      if (!params.has('pool')){
        M.toast({html: 'must specify pool name'})
        return;
      }
      poolName = params.get('pool');
      var createURL = "/create_instance.html?origin=list&pool=" + poolName;
      var batchCreateURL = "batch_create_instance.html?pool=" + poolName;
      $('#breadcrumb-path').append(
        $('<a>').addClass('breadcrumb').text(poolName).attr('href','compute_cells.html?pool=' + poolName)
      );
      if (params.has('cell')){
        cellName = params.get('cell');
        createURL += "&cell=" + cellName;
        batchCreateURL += "&cell=" + cellName;
        $('#breadcrumb-path').append(
          $('<a>').addClass('breadcrumb').text(cellName).attr('href','#')
        );
      }
      $('#breadcrumb-path').append(
        $('<a>').addClass('breadcrumb').text(texts.get(N.TagInstance)).attr('href','#')
      );

      $('#create_button').attr('href',  createURL);
      $('#batch_create_button').attr('href', batchCreateURL);

      disableBatchMode();
    });

</script>
</body>
</html>
